package hn.sigit.logic.viewer.toolbox;

import hn.sigit.dao.hnd.administrative.HND_PropertyDAO;
import hn.sigit.dao.hnd.ladmshadow.PartyDAO;
import hn.sigit.dao.hnd.ladmshadow.PropertyDAO;
import hn.sigit.dao.hnd.ladmshadow.RRRDAO;
import hn.sigit.dao.ladm.administrative.LA_RRRDAO;
import hn.sigit.dao.ladm.party.LA_PartyDAO;
import hn.sigit.model.commons.IProperty;
import hn.sigit.model.commons.IRRR;
import hn.sigit.model.hnd.administrative.HND_Property;
import hn.sigit.model.hnd.ladmshadow.Party;
import hn.sigit.model.hnd.ladmshadow.Property;
import hn.sigit.model.hnd.ladmshadow.RRR;
import hn.sigit.model.ladm.administrative.LA_RRR;
import hn.sigit.model.ladm.party.LA_Party;
import hn.sigit.util.ShareValue;

import java.util.Date;
import java.util.List;
import java.util.Set;

public class RRRHelperLogic {
	public static <U extends ParcelRRR<?>> void modifySelected(List<U> parcelRRRList, List<U> newParcelRRRList) {
		for (U pr : parcelRRRList)
			if (pr.isSelected() && !newParcelRRRList.contains(pr))
				newParcelRRRList.add(pr);
	}
	
	public static <U extends ParcelRRR<?>> void cancelRRRsModification(List<U> parcelRRRsList) {
		for (ParcelRRR<?> pr : parcelRRRsList) {
			pr.setSelected(false);
			pr.cancelChanges();
		}
		parcelRRRsList.clear();
	}

	public static <U extends ParcelRRR<?>> void acceptRRRsModification(List<U> parcelRRRsList, List<U> newParcelRRRsList) {
		for (U pr : newParcelRRRsList) {
			pr.setSelected(false);
			pr.applyChanges();
			if (pr.isNewRRR() && !parcelRRRsList.contains(pr))
				parcelRRRsList.add(pr);
		}
		newParcelRRRsList.clear();
	}
	
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public static <U extends ParcelRRR<?>, IR extends IRRR> void applyRRRChanges(IProperty property,
			Set<IR> rrrSet, List<U> parcelRRRsList, List<ParcelRRR> rrrsToDelete) {
		IR rrr;
		
		//Add to the RRR set the new created right entries
		for (ParcelRRR<?> pr : parcelRRRsList) {
			if (pr.isModified()) {
				rrr = (IR) pr.getRrr();
				
				if (rrr.getBeginLifespanVersion() == null)
					rrr.setBeginLifespanVersion(new Date());
				
				if (rrr instanceof RRR)
					RRRDAO.save(rrr);
				else if (rrr instanceof LA_RRR)
					LA_RRRDAO.save(rrr);
				
				if ( !rrrSet.contains(rrr) ) {
					if (rrr.getParty() instanceof Party)
						PartyDAO.save(rrr.getParty());
					else if (rrr.getParty() instanceof LA_Party)
						LA_PartyDAO.save(rrr.getParty());
					rrr.setBaunit(property);
					rrrSet.add(rrr);
				}
			}
		}
		
		//Delete from the RRR set the right entries deleted from the UI
		for (ParcelRRR<?> prrr : rrrsToDelete)
			if ( rrrSet.contains(prrr.getRrr()) ) {
				rrrSet.remove(prrr.getRrr());
				RRRDAO.delete(prrr.getRrr());
			}
		rrrsToDelete.clear();
		
		//Does this also saves entries modified directly?
		if (property instanceof Property)
			PropertyDAO.save(property);
		else if (property instanceof HND_Property)
			HND_PropertyDAO.save(property);
	}

	@SuppressWarnings("rawtypes")
	public static <U extends ParcelRRR<?>> void deleteSelectedRRRs(List<U> parcelRRRsList, List<ParcelRRR> rrrsToDelete) {
		int i = 0;
		while (i < parcelRRRsList.size()) {
			if ( parcelRRRsList.get(i).isSelected() ) {
				rrrsToDelete.add(parcelRRRsList.get(i));
				parcelRRRsList.remove(i);
			}
			else
				i++;
		}
	}
	
	@SuppressWarnings("rawtypes")
	public static ShareValue getSumShares(List<? extends ParcelRRR> parcelRRRsList) {
		ShareValue sumShares = new ShareValue();
		if (null != parcelRRRsList)
			for (ParcelRRR<?> pr : parcelRRRsList)
				if (pr != null)
					sumShares.addOther(pr.getShare());
		return sumShares;
	}
	
}
